/********************************** (C) COPYRIGHT *******************************
* File Name          : IIC.C
* Author             : Yuimerlin
* Version            : V1.0
* Date               : 2022/6/10
* Description        : CH549 模拟IIC相关函数
*******************************************************************************/
#include "CH549_IIC.h"

//初始化I2C
void IIC_Init()
{
    GPIO_Init(PORT0,PIN5,MODE2);
    GPIO_Init(PORT0,PIN6,MODE2);//CH549电压为5V，而非3.3V
}

//开始
void IIC_Start()
{
	SDA_UP;
    SCL_UP; 
	mDelayuS(4);
	SDA_DOWN;
	mDelayuS(4);
	SCL_DOWN;
}

//结束
void IIC_Stop()
{
    SCL_DOWN;
	SDA_DOWN;
	mDelayuS(4);
	SCL_UP;
	SDA_UP;
	mDelayuS(4);
}

//返回值：1.接收应答失败；0.接收应答成功。
UINT8 IIC_Wait_Ack()
{
	UINT32 t=0;
	SDA_UP; 
	mDelayuS(1);
	SCL_UP; 
	mDelayuS(1);
	while(SDA_READ)
	{
		t++;
		if(t > 250)
		{
			IIC_Stop();
			return 1;
		}
	}
	SCL_DOWN;
	return 0;	
}

//不产生ACK应答
void IIC_Nack()
{
	SCL_DOWN;
	SDA_UP;
	mDelayuS(2);
	SCL_UP;
	mDelayuS(2);
	SCL_DOWN;
}

//产生ACK应答
void IIC_Ack()
{
    SCL_DOWN;
	SDA_DOWN;
	mDelayuS(2);
	SCL_UP;
	mDelayuS(2);
	SCL_DOWN;
}

//I2C发送一个字节
void IIC_Send_Byte(UINT8 byte)
{
	UINT8 i;
    SCL_DOWN;
	for( i = 0 ; i < 8 ; i++ )
    {
		if(byte&0x80)
        {
			SDA_UP;
		}else
        {
			SDA_DOWN;
		}
	byte <<= 1;
    mDelayuS(2);
	SCL_UP;
	mDelayuS(2);
	SCL_DOWN;
	mDelayuS(2);
	}
}

//读1个字节，ack=1时，发送ack；ack=0时发送nack
UINT8 IIC_Read_Byte(UINT8 ack)
{
	UINT8 i = 0;
	UINT8 receive = 0;
	for( i = 0 ; i < 8 ; i++ )
    {
		SCL_DOWN;
        mDelayuS(2);
        SCL_UP;
        receive <<= 1;
		if(SDA_READ)
        {
			receive++; 
		}
        mDelayuS(1);
	}
	if (!ack)
    {
        IIC_Nack();
    }else
    {
        IIC_Ack();
    }
    return receive;
}